package com.cnap.multiclouldmgmt.controller;

import com.cnap.multiclouldmgmt.model.CommonResult;
import com.cnap.multiclouldmgmt.model.RepByPage;
import com.cnap.multiclouldmgmt.model.scale.QueryScalingConfigParam;
import com.cnap.multiclouldmgmt.model.scale.ScalingConfigDTO;
import com.cnap.multiclouldmgmt.model.scale.ScalingConfigVO;
import com.cnap.multiclouldmgmt.model.scale.db.ScalingResourcePO;
import com.cnap.multiclouldmgmt.model.scale.group.QueryScalingGroupParam;
import com.cnap.multiclouldmgmt.model.scale.group.ScalingGroupDTO;
import com.cnap.multiclouldmgmt.model.scale.group.ScalingGroupVO;
import com.cnap.multiclouldmgmt.model.scale.intelligent.QueryThresholdParam;
import com.cnap.multiclouldmgmt.model.scale.policy.ScalingPolicyDTO;
import com.cnap.multiclouldmgmt.service.ScalingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * 资源弹性伸缩控制类
 *
 * @author xc
 **/
@Api(tags = "混合云网管理-资源弹性伸缩")
@RequestMapping(path = "/cnap/multicloudmgmt/v1/scaling")
@RestController
public class ScalingController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ScalingController.class);
    private final ScalingService scalingService;

    @Autowired
    public ScalingController(ScalingService scalingService) {
        this.scalingService = scalingService;
    }

    /**
     * 根据关键字查询伸缩组列表
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "1-1 根据关键字查询伸缩组列表", httpMethod = "POST", notes = "查询伸缩组列表")
    @PostMapping("/group/list")
    public CommonResult<RepByPage<ScalingGroupVO>> getScalingGroup(@RequestBody QueryScalingGroupParam param) {
        RepByPage<ScalingGroupVO> repByPage = scalingService.findByPage(param);

        return CommonResult.success(repByPage);
    }

    /**
     * 创建伸缩组
     *
     * @param scalingGroupDTO
     * @return
     */
    @ApiOperation(value = "1-2 创建伸缩组", httpMethod = "POST", notes = "创建伸缩组")
    @PostMapping("/group/add")
    public CommonResult<String> createScalingGroup(@RequestBody ScalingGroupDTO scalingGroupDTO) {
        LOGGER.info("[scaling]: create new scaling group: {}", scalingGroupDTO);
        boolean result = scalingService.createScalingGroup(scalingGroupDTO);
        return result ? CommonResult.successMsg("创建伸缩组成功") : CommonResult.failed("创建伸缩组失败");
    }

    /**
     * 创建伸缩策略
     *
     * @param scalingPolicyDTOs
     * @return
     */
    @ApiOperation(value = "1-3 创建伸缩策略", httpMethod = "POST", notes = "创建伸缩策略")
    @PostMapping("/policy/add")
    public CommonResult<String> createScalingPolicy(@RequestBody List<ScalingPolicyDTO> scalingPolicyDTOs) {
        LOGGER.info("[scaling]: create new scaling policy: {}", scalingPolicyDTOs);
        boolean result = scalingService.createScalingPolicy(scalingPolicyDTOs);
        return result ? CommonResult.successMsg("创建伸缩策略成功") : CommonResult.failed("创建伸缩策略失败");
    }

    /**
     * 根据关键字查询伸缩配置
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "1-4 根据关键字查询伸缩配置", httpMethod = "POST", notes = "查询伸缩配置")
    @PostMapping("/config/list")
    public CommonResult<RepByPage<ScalingConfigVO>> getScalingGroup(@RequestBody QueryScalingConfigParam param) {
        LOGGER.info("[scaling]: query scaling config: {}", param);
        RepByPage<ScalingConfigVO> repByPage = scalingService.findByPage(param);

        return CommonResult.success(repByPage);
    }

    /**
     * 创建伸缩配置
     *
     * @param scalingConfigDTO
     * @return
     */
    @ApiOperation(value = "1-5 创建伸缩配置", httpMethod = "POST", notes = "创建伸缩配置")
    @PostMapping("/config/add")
    public CommonResult<String> createScalingConfig(@RequestBody ScalingConfigDTO scalingConfigDTO) {
        LOGGER.info("[scaling]: create new scaling config: {}", scalingConfigDTO);
        boolean result = scalingService.createScalingConfig(scalingConfigDTO);
        return result ? CommonResult.successMsg("创建伸缩配置成功") : CommonResult.failed("创建伸缩配置失败");
    }

    /**
     * 启用伸缩组策略
     *
     * @param groupId
     * @return
     */
    @ApiOperation(value = "1-6 启用伸缩组策略", httpMethod = "GET", notes = "启用伸缩组策略")
    @GetMapping("/group/start/{groupId}")
    public CommonResult<String> startScalingPolicy(@PathVariable("groupId") String groupId) {
        LOGGER.info("[scaling]: start scaling policy groupId={}", groupId);
        boolean result = scalingService.startScale(groupId);
        return result ? CommonResult.successMsg("启用伸缩策略成功") : CommonResult.failed("启用伸缩策略失败");
    }

    /**
     * 停用伸缩组策略
     *
     * @param groupId
     * @return
     */
    @ApiOperation(value = "1-7 停用伸缩组策略", httpMethod = "GET", notes = "停用伸缩组策略")
    @GetMapping("/group/stop/{groupId}")
    public CommonResult<String> stopScalingPolicy(@PathVariable("groupId") String groupId) {
        LOGGER.info("[scaling]: stop scaling policy groupId={}", groupId);
        boolean result = scalingService.stopScale(groupId);
        return result ? CommonResult.successMsg("停用伸缩组策略成功") : CommonResult.failed("停用伸缩组策略失败");
    }

    /**
     * 删除伸缩组策略
     *
     * @param groupId
     * @return
     */
    @ApiOperation(value = "1-8 删除伸缩组策略", httpMethod = "DELETE", notes = "停用伸缩组策略")
    @DeleteMapping("/group/delete/{groupId}")
    public CommonResult<String> deleteScalingPolicy(@PathVariable("groupId") String groupId) {
        LOGGER.info("[scaling]: delete scaling policy groupId={}", groupId);
        boolean result = scalingService.deleteScalingGroup(groupId, true);
        return result ? CommonResult.successMsg("删除伸缩组策略成功") : CommonResult.failed("删除伸缩组策略失败");
    }

    /**
     * 删除伸缩配置
     *
     * @param deleteId
     * @return
     */
    @ApiOperation(value = "1-9 删除伸缩配置", httpMethod = "DELETE", notes = "删除伸缩配置")
    @DeleteMapping("/config/delete/{deleteId}")
    public CommonResult<String> deleteScalingConfig(@PathVariable("deleteId") String deleteId) {
        LOGGER.info("[scaling]: delete scaling config configId={}", deleteId);
        boolean result = scalingService.deleteScalingConfigById(deleteId);
        return result ? CommonResult.successMsg("删除伸缩配置成功") : CommonResult.failed("删除伸缩配置失败");
    }

    /**
     * 查询所有配置规格
     *
     * @return 结果
     */
    @ApiOperation(value = "1-11 查询所有配置规格", httpMethod = "GET", notes = "查询所有配置规格")
    @GetMapping("/resource/all")
    public CommonResult<List<ScalingResourcePO>> getAllResources() {
        List<ScalingResourcePO> resourcePOS = scalingService.getAllCloudResources();
        return CommonResult.success(resourcePOS);
    }

    @ApiOperation(value = "1-12 根据id查询配置规格", httpMethod = "GET", notes = "根据id查询配置规格")
    @GetMapping("/resource/{id}")
    public CommonResult<ScalingResourcePO> getResourceById(@PathVariable("id") String resourceId) {
        LOGGER.info("[scaling]: query scaling resource by id={}", resourceId);
        ScalingResourcePO resourcePO = scalingService.getCloudResourceById(resourceId);
        return CommonResult.success(resourcePO);
    }

    @ApiOperation(value = "1-14 查询智能告警阈值", httpMethod = "POST", notes = "查询智能告警阈值")
    @PostMapping("/intelligent/threshold")
    public CommonResult<String> getIntelligentAlarmThreshold(@Validated @RequestBody QueryThresholdParam queryThresholdParam) {

        if (StringUtils.isEmpty(queryThresholdParam.getResType())){
            queryThresholdParam.setResType("微服务");
            queryThresholdParam.setNodeNames(new ArrayList<>());
        }

        String value = scalingService.getIntelligentThreshold(queryThresholdParam);
        return CommonResult.success(value);
    }

}
